/*
 * Created by Wildish on 2016-10-31
 *
 * Contact me with keithknight@qq.com
 *
 * Copyright (c) 2016 Wildish
 */

package com.wildish.hybridframework.utils;

import com.wildish.hybridframework.core.HybridGlobal;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;

public class HttpBaseHelper {
	private static final String DEFAULT_CHARSET = "UTF-8";
    public static final String CONTENT_TYPE = "Content-Type";
    public static final String CONTENT_TYPE_TEXT = "application/x-www-form-urlencoded;charset=utf-8";
    public static final String CONTENT_TYPE_JSON = "application/json;charset=utf-8";
    public static final String CONTENT_TYPE_PLAIN = "text/plain;charset=utf-8";

    /**
     * get result from server without https
     */
    public static String doGet(String url, String paramsEntry, HashMap<String, String> headers) throws NoSuchAlgorithmException,
            NoSuchProviderException, IOException, KeyManagementException {
        StringBuffer bufferRes = null;
        URL urlGet = new URL(url);
        HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
        // 连接超时
        http.setConnectTimeout(25000);
        // 读取超时 --服务器响应比较慢，增大时间
        http.setReadTimeout(25000);
        http.setRequestMethod("GET");
        if(!headers.isEmpty()) {
            for(Map.Entry<String, String> entry : headers.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                http.setRequestProperty(key, value);
            }
        }
        http.setDoOutput(true);
        http.setDoInput(true);
        http.connect();

        OutputStream out = http.getOutputStream();
        out.write(paramsEntry.getBytes("UTF-8"));
        out.flush();
        out.close();

        InputStream in = http.getInputStream();
        BufferedReader read = new BufferedReader(new InputStreamReader(in, DEFAULT_CHARSET));
        String valueString = null;
        bufferRes = new StringBuffer();
        while ((valueString = read.readLine()) != null) {
            bufferRes.append(valueString);
        }
        in.close();

        HybridGlobal.logger.log("=============== 请求监控begin ===============");
        HybridGlobal.logger.log("code:" + http.getResponseCode());
        HybridGlobal.logger.log("链接:" + url);
        HybridGlobal.logger.log("参数:" + paramsEntry);
        HybridGlobal.logger.log("返回结果:" + bufferRes.toString());
        HybridGlobal.logger.log("=============== 请求监控end =================");

        if (http != null) {
            // 关闭连接
            http.disconnect();
        }
        return bufferRes.toString();
    }

	/**
	 * 多文件上传
	 * @param actionUrl
	 * @param textParams
	 * @param filePaths
	 * @return
	 */
	public static String postWithFiles(String actionUrl, Map<String, String> textParams, String[] filePaths) {
		try {
			final String BOUNDARY = UUID.randomUUID().toString();
			final String PREFIX = "--";
			final String LINE_END = "\r\n";

			final String MULTIPART_FROM_DATA = "multipart/form-data";
			final String CHARSET = "UTF-8";

			URL uri = new URL(actionUrl);
			HttpURLConnection conn = (HttpURLConnection) uri.openConnection();

			//缓存大小
			conn.setChunkedStreamingMode(1024 * 64);
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setUseCaches(false);
			conn.setRequestMethod("POST");

			conn.setRequestProperty("connection", "keep-alive");
			conn.setRequestProperty("Charset", "UTF-8");
			conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);

			// 拼接文本类型的参数
			StringBuilder textSb = new StringBuilder();
			if (textParams != null) {
				for (Map.Entry<String, String> entry : textParams.entrySet()) {
					textSb.append(PREFIX).append(BOUNDARY).append(LINE_END);
					textSb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINE_END);
					textSb.append("Content-Type: text/plain; charset=" + CHARSET + LINE_END);
					textSb.append("Content-Transfer-Encoding: 8bit" + LINE_END);
					textSb.append(LINE_END);
					textSb.append(entry.getValue());
					textSb.append(LINE_END);
				}
			}
			DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
			outStream.write(textSb.toString().getBytes());

			// 发送文件数据
			if (filePaths != null) {
				for (String file : filePaths) {
					StringBuilder fileSb = new StringBuilder();
					fileSb.append(PREFIX).append(BOUNDARY).append(LINE_END);
					fileSb.append("Content-Disposition: form-data; name=\"file\"; filename=\"" +
							file.substring(file.lastIndexOf("/") + 1) + "\"" + LINE_END);
					fileSb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END);
					fileSb.append(LINE_END);
					outStream.write(fileSb.toString().getBytes());

					InputStream is = new FileInputStream(file);
					byte[] buffer = new byte[1024 * 8];
					int len;
					while ((len = is.read(buffer)) != -1) {
						outStream.write(buffer, 0, len);
					}
					is.close();
					outStream.write(LINE_END.getBytes());
				}
			}

			// 请求结束标志
			outStream.write((PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes());
			outStream.flush();

			// 得到响应码
			int responseCode = conn.getResponseCode();
			BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), CHARSET));

			StringBuilder resultSb = null;
			String line;
			if (responseCode == 200) {
				resultSb = new StringBuilder();
				while ((line = br.readLine()) != null) {
					resultSb.append(line).append("\n");
				}
			}
			br.close();
			outStream.close();
			conn.disconnect();
			return resultSb == null ? null : resultSb.toString();
		} catch (IOException e) {
			HybridGlobal.logger.log(e);
		}
		return null;
	}

    public static JSONObject hashMap2JSON(HashMap<String, String> hashMap) {
        JSONObject result = new JSONObject();
        try{
            for(Iterator<Map.Entry<String,String>> it = hashMap.entrySet().iterator(); it.hasNext();) {
                Map.Entry<String,String> entry = it.next();
                String key = entry.getKey();
                String value = entry.getValue();

                result.put(key, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }
}